<template>
  <div class="note-richtext" :class="rootClass">
    <template v-for="(seg, idx) in segments" :key="idx">
      <span v-if="seg.type === 'text'" class="seg-text">{{ seg.text }}</span>

      <v-chip
        v-else-if="seg.type === 'user'"
        class="seg-chip mr-1 mb-1 border-white"
        color="warning"
        density="comfortable"
        :ripple="true"
        rounded="pill"
        size="small"
        variant="flat"
        @click="onUserClick(seg)"
      >
        <v-icon :icon="mdiAt" size="16" start /> {{ seg.name }}
      </v-chip>

      <v-chip
        v-else-if="seg.type === 'contact'"
        class="seg-chip mr-1 mb-1 border-white"
        color="success"
        density="comfortable"
        :ripple="true"
        rounded="pill"
        size="small"
        variant="flat"
        @click="onContactClick(seg)"
      >
        <v-icon :icon="mdiAccountBox" size="16" start /> {{ seg.name }}
      </v-chip>

      <v-chip
        v-else-if="seg.type === 'company'"
        class="seg-chip mr-1 mb-1 border-white"
        color="info"
        density="comfortable"
        :ripple="true"
        rounded="pill"
        size="small"
        variant="flat"
        @click="onCompanyClick(seg)"
      >
        <v-icon :icon="mdiDomain" size="16" start /> {{ seg.name }}
      </v-chip>
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { mdiAccountBox, mdiAt, mdiDomain } from '@mdi/js'

interface TextSeg {
  type: 'text'
  text: string
}
interface UserSeg {
  type: 'user'
  name: string
  userId: number
}
interface ContactSeg {
  type: 'contact'
  name: string
  contactId: number
  companyId: number
}
interface CompanySeg {
  type: 'company'
  name: string
  companyId: number
}

type Seg = TextSeg | UserSeg | ContactSeg | CompanySeg

const props = defineProps<{
  content: string
  /** 可选：应用 2 行/3 行等文本收缩样式时，可由父级提供相应 class，如 line-clamp-2 */
  rootClass?: string | string[] | Record<string, boolean>
}>()

const emit = defineEmits<{
  (e: 'click-user', payload: { id: number; name: string }): void
  (e: 'click-contact', payload: { contactId: number; companyId: number; name: string }): void
  (e: 'click-company', payload: { id: number; name: string }): void
}>()

// {[@Name,1]} | {[#Name,1500869,454079]} | {[$Company,454079]}
const TOKEN_RE = /\{\[\s*([@#$])\s*([^,\]]+)\s*,\s*(\d+)(?:\s*,\s*(\d+))?\s*]}/g

function parse(content: string): Seg[] {
  if (!content) return []
  const segs: Seg[] = []
  let last = 0
  let m: RegExpExecArray | null
  while ((m = TOKEN_RE.exec(content))) {
    const [raw, kind, nameRaw, id1Raw, id2Raw] = m
    const start = m.index
    const end = start + raw.length

    if (start > last) segs.push({ type: 'text', text: content.slice(last, start) })

    const name = (nameRaw ?? '').trim()
    const id1 = Number(id1Raw)
    const id2 = id2Raw ? Number(id2Raw) : undefined

    switch (kind) {
      case '@': {
        segs.push({ type: 'user', name, userId: id1 })

        break
      }
      case '#': {
        if (id2 === undefined) {
          segs.push({ type: 'text', text: raw })
        } else {
          segs.push({ type: 'contact', name, contactId: id1, companyId: id2 })
        } // 容错：结构不完整，还原原文

        break
      }
      case '$': {
        segs.push({ type: 'company', name, companyId: id1 })

        break
      }
      default: {
        segs.push({ type: 'text', text: raw })
      }
    }

    last = end
  }
  if (last < content.length) segs.push({ type: 'text', text: content.slice(last) })
  return segs
}

const segments = computed(() => parse(props.content))

function onUserClick(seg: UserSeg) {
  emit('click-user', { id: seg.userId, name: seg.name })
}
function onContactClick(seg: ContactSeg) {
  emit('click-contact', { contactId: seg.contactId, companyId: seg.companyId, name: seg.name })
}
function onCompanyClick(seg: CompanySeg) {
  emit('click-company', { id: seg.companyId, name: seg.name })
}
</script>

<style scoped>
.note-richtext {
  /* 保留换行与空白 */
  white-space: pre-wrap;
  word-break: break-word;
}
.seg-text {
  /* 让文本与 chip 共行排列 */
  display: inline;
  vertical-align: middle;
}
.seg-chip {
  font-size: 11px !important;
  display: inline-flex;
  vertical-align: middle;
  align-items: center;
  cursor: pointer;
  font-weight: bold;
  opacity: 0.9;
}
</style>
